define(['jquery', 'iQuery+'],  function ($) {

    function Schedule($_View, iFallback) {

        $.CommonView.call(this, $_View).on('conflict', iFallback);

        this.map = [0, 0, 0, 0, 0, 0, 0];

        this.length = 0;
    }

    return  $.inherit($.CommonView, Schedule, {
        getMaskCode:    function (Index) {
            return  (Index < 0)  ?  0  :  parseInt(1 + '0'.repeat(Index),  2);
        }
    }, {
        push:         Array.prototype.push,
        splice:       Array.prototype.splice,
        checkDate:    function (iDate) {

            for (var i = 0;  i < this.map.length;  i++)
                if ((this.map[i] ^ iDate[i])  !=  (this.map[i] + iDate[i]))
                    return false;

            return true;
        },
        update:       function (iDate) {

            for (var i = 0;  i < this.map.length;  i++)
                this.map[i] ^= iDate[i];

            return this;
        },
        date2Cell:    function (iDate) {
            var $_Day = this.$_View[0].children;

            return  $($.map(iDate,  function (iPos, iDay) {

                return  $.map(iPos.toString(2).split('').reverse(),  function () {

                    return  parseInt( arguments[0] )  ?
                        $_Day[ iDay ].children[arguments[1] + 1]  :  null;
                });
            }));
        },
        render:       function (iData) {

            for (var i = 0;  iData[i];  i++)
                if (this.checkDate( iData[i].date )) {

                    this.update( iData[i].date ).push( iData[i] );

                    this.date2Cell( iData[i].date ).text( iData[i].name );

                } else if (false === this.trigger('conflict', [iData[i]]))
                    break;

            if ( iData[0] )  this.trigger('afterRender', [iData]);

            return this;
        },
        indexOf:      function (iDOM) {
            var iMask = Schedule.getMaskCode($(iDOM).prevAll().length - 1),
                iRow = $( iDOM.parentElement ).prevAll().length;

            for (var i = 0;  this[i];  i++)
                if (this[i].date[iRow] & iMask)
                    return i;

            return -1;
        },
        remove:       function () {
            var Index = this.indexOf( arguments[0] );

            var iDate = (Index > -1)  &&  this.splice(Index, 1)[0].date;

            if ( iDate )  this.update( iDate ).date2Cell( iDate ).empty();

            return this;
        }
    });
});